package 创建线程的四种方式;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 核心线程数<=最大线程数，否则会报错
 * 任务来之前线程池中无线程，任务来了先创建核心线程(懒加载)，其余任务进入阻塞队列，阻塞队列满了，使用非核心线程（最大线程-核心线程），当非核心线程超过存活时间会被回收
 * 最大线程数包括核心线程数，最大线程数为瓶身加瓶口，不包括瓶颈
 * 最大线程+阻塞队列满了，执行拒绝策略
 * threadPoolExecutor.getActiveCount(),线程池中正在使用的线程，不包括空闲的线程
 * threadPoolExecutor.getPoolSize()，线程池中存在的线程，包括空闲的和正在使用的
 */
public class AbortStrategy {
    public static void main(String[] args) throws InterruptedException {
//        最大线程和阻塞队列满了抛出异常
//        abortPolicy();

//        满了直接丢弃任务，任务消失，并且没有异常提示
//        discardPolicy();

//        满了直接丢给main线程处理
//        callerRunsPolicy();

//        队列满了，尝试去和最早得竞争，也不会抛出异常,也不会丢弃任务
        discardOldestPolicy();
    }
    public static void abortPolicy() {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
                5,
                3,
                TimeUnit.SECONDS,
//                LinkedBlockingQueue默认为integer的最大值
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
        for (int i = 0; i < 9; i++) {
            int tmp = i;
            threadPoolExecutor.execute(() ->{
                String name = Thread.currentThread().getName();
                System.out.println(name + ":" +tmp);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        // 线程池用完,程序结束,关闭线程池
        try {
            threadPoolExecutor.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }

    public static void discardPolicy() throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
                5,
                3,
                TimeUnit.SECONDS,
//                LinkedBlockingQueue默认为integer的最大值
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardPolicy()
        );
        for (int i = 0; i < 9; i++) {
            int tmp = i;
            threadPoolExecutor.execute(() ->{
                String name = Thread.currentThread().getName();
                System.out.println(name + ":" +tmp);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        // 线程池用完,程序结束,关闭线程池
        try {
            threadPoolExecutor.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }

    public static void callerRunsPolicy() throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
                5,
                3,
                TimeUnit.SECONDS,
//                LinkedBlockingQueue默认为integer的最大值
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
        String name1 = Thread.currentThread().getName();
        System.out.println(name1);
        for (int i = 0; i < 9; i++) {
            int tmp = i;
            threadPoolExecutor.execute(() ->{
                String name = Thread.currentThread().getName();
                System.out.println(name + ":" +tmp);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        // 线程池用完,程序结束,关闭线程池
        try {
            threadPoolExecutor.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }

    public static void discardOldestPolicy() throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
                5,
                3,
                TimeUnit.SECONDS,
//                LinkedBlockingQueue默认为integer的最大值
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy()
        );
        for (int i = 0; i < 10; i++) {
            int tmp = i;
            threadPoolExecutor.execute(() ->{
                String name = Thread.currentThread().getName();
                System.out.println(name + ":" +tmp);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        // 线程池用完,程序结束,关闭线程池
        try {
            threadPoolExecutor.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }

}
